/**
 * @author cqb 2016-04-05.
 * @module Spinner
 */

import React from 'react';
import classNames from 'classnames';
import Input from '../Input/index';
import FormItem from '../FormItem';
import Icon from '../Icon';
import './Spinner.less';

/**
 * Spinner
 * @class Spinner
 * @extends {BaseComponent}
 */
class Spinner extends React.Component {
    static displayName = 'Spinner';

    static defaultProps = {
        value: 0,
        step: 1,
        size: 'default',
        loop: false,
        min: 0
    };

    state = {
        _value: this.props.value
    }

    /**
     * 增加
     * @memberof Spinner
     */
    plus = () => {
        const {min, max, step, loop, value} = this.props;
        let v = this.add(value, step);
        if (loop && max !== undefined && min !== undefined && v > max) {
            const off = v - max;
            v = min + off - 1;
        }

        if (max !== undefined) {
            v = Math.min(max, v);
        }
        
        if (this.props.onChange) {
            this.props.onChange(v);
        }
        if (this.props.onPlus) {
            this.props.onPlus(v, step);
        }
    }

    /**
     * 减少
     * @memberof Spinner
     */
    sub = () => {
        const {min, max, step, loop, value} = this.props;
        let v = this.add(value, -step);
        if (loop && max !== undefined && min !== undefined && v < min) {
            const off = v - min;
            v = max + off + 1;
        }
        if (min !== undefined) {
            v = Math.max(min, v);
        }
        
        if (this.props.onChange) {
            this.props.onChange(v);
        }
        if (this.props.onSub) {
            this.props.onSub(v, step);
        }
    }

    onChange = (value) => {
        let val = value;
        if (this.props.max !== undefined) {
            if (val > this.props.max) {
                val = this.props.max;
            }
        }
        if (this.props.min !== undefined) {
            if (val < this.props.min) {
                val = this.props.min;
            }
        }
        if (this.props.onChange) {
            this.props.onChange(val);
        }
    }

    /**
     * 解决数字浮点型双精度问题
     * @param {[type]} num1 [description]
     * @param {[type]} num2 [description]
     */
    add (num1, num2) {
        let r1;
        let r2;
        let m;
        try {
            r1 = num1.toString().split('.')[1].length;
        } catch (e) {
            r1 = 0;
        }
        try {
            r2 = num2.toString().split('.')[1].length;
        } catch (e) {
            r2 = 0;
        }
        m = Math.pow(10, Math.max(r1, r2));
        return (num1 * m + num2 * m) / m;
    }

    onKeyDown = (e) => {
        if (e.keyCode === 38) {
            this.plus();
        }
        if (e.keyCode === 40) {
            this.sub();
        }
    }

    onInput = (e) => {
        let value = e.target.value;
        value = value.replace(/[^0-9\.]/g, '');
        e.target.value = value;
    }

    render () {
        let {className, style, value} = this.props;
        className = classNames('cm-spinner', className, {
            [`cm-spinner-${this.props.size}`]: this.props.size
        });
        return (
            <div className={className} style={style}>
                <span className='cm-spinner-value'>
                    <Input ref={f => this.input = f } onInput={this.onInput}
                        name={this.props.name} value={value} onChange={this.onChange} onKeyDown={this.onKeyDown}/>
                </span>
                <span className='cm-spinner-plus' onClick={this.plus}>
                    <Icon name='chevron-up' size={12}/>
                </span>
                <span className='cm-spinner-subs' onClick={this.sub}>
                    <Icon name='chevron-down' size={12}/>
                </span>
            </div>
        );
    }
}

FormItem.register(Spinner, 'spinner');

export default Spinner;
